package com.ruoyi.system.service.impl;


import cn.hutool.core.date.DateTime;
import com.ruoyi.system.websocket.MessageForm;
import com.ruoyi.system.domain.Message;
import com.ruoyi.common.utils.AssertUtils;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.websocket.WebSocket;
import com.ruoyi.system.websocket.WebSocketUtil;

import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.system.mapper.MessageMapper;
import com.ruoyi.system.mapper.SysUserMapper;

import com.ruoyi.system.service.IMessageService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 参数配置 服务层实现
 *
 * @author chen
 */

@Service
public class MessageServiceImpl implements IMessageService {

    @Autowired
    private WebSocketUtil webSocketUtil;
    // 限制聊天记录数量
    final Integer limitMessagesLength = 6000;
    // 限制用户数量
    final Integer limitUserLength = 10;

    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private MessageMapper messageMapper;



    @Override
    // 获取未读的接收信息
    public Integer findNoReadMessageLength( String userId) throws Exception {
        try {

            Integer totol = 0;
            AssertUtils.isError(StringUtils.isEmpty(userId), "用户编号不能为空!");
            SysUser user = userMapper.selectUserById(Long.valueOf((userId)));
            AssertUtils.isError(null == user, "用户编号:" + userId + "不存在!");
            Map<String, Object> params = new HashMap<>();
            params.put("userId", userId); // userId 是ReceiveUser的 id
            params.put("limitMessagesLength", limitMessagesLength); // 假设要限制返回的数量为 limitMessagesLength 条
            // 为防止发送人特别多导致信息未获取，这里多设置一些拿信息数据
            List<Message> messages = messageMapper
                    .selectByReceiveUserLimitLength(params);
            Map<String, List<Message>> messageBySendUserMap = messages.stream()
                    .collect(Collectors.groupingBy(Message::getSendUser));
            for (String sendUser : messageBySendUserMap.keySet()) {
                List<Message> receiveMessageList = messageBySendUserMap.get(sendUser);
                Integer noReadSize = receiveMessageList.stream().filter(o -> "0".equals(o.getIsRead()))
                        .collect(Collectors.toList()).size();
                totol += noReadSize;
            }
            return totol;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }
    @Override
    // 发送信息的逻辑
    public void sendMessage( Message message) throws Exception {
        try {
            AssertUtils.isError(StringUtils.isEmpty(message.getSendUser()), "发送用户不能为空!");
            AssertUtils.isError(StringUtils.isEmpty(message.getReceiveUser()), "接收用户不能为空!");
            AssertUtils.isError(StringUtils.isEmpty(message.getContent()), "发送信息不能为空!");
            SysUser sendUser = userMapper.selectUserById(Long.valueOf(message.getSendUser()));
            AssertUtils.isError(null == sendUser, "发送用户不存在,发送信息失败!");
            AssertUtils.isError(!Objects.equals(sendUser.getStatus(), "0"),
                    "发送用户:" + message.getSendUser() + "状态已冻结,无法发送信息!");
            SysUser receiveUser = userMapper.selectUserById(Long.valueOf(message.getReceiveUser()));
            AssertUtils.isError(null == receiveUser, "接收用户不存在,发送信息失败!");
            AssertUtils.isError(!Objects.equals(receiveUser.getStatus(), "0"),
                    "接收用户:" + message.getReceiveUser() + "状态已冻结,无法接收信息!");
            message.setHandle(UUID.randomUUID().toString());
            message.setIsRead("0");
            message.setCreateTime(DateTime.now());
            messageMapper.insert(message);
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    @Override
    // 获取两个人的聊天记录
    public List<Message> findMessageBySendUserAndReceiveUser( String sendUserId,
                                                             String receiveUserId) throws Exception {
        try {
            AssertUtils.isError(StringUtils.isEmpty(sendUserId), "发送用户为空!");
            AssertUtils.isError(StringUtils.isEmpty(receiveUserId), "接收用户为空!");
            SysUser sendUser = userMapper.selectUserById(Long.valueOf(sendUserId));
            AssertUtils.isError(null == sendUser, "发送用户不存在,发送信息失败!");
            SysUser receiveUser = userMapper.selectUserById(Long.valueOf(receiveUserId));
            AssertUtils.isError(null == receiveUser, "接收用户不存在,发送信息失败!");
            Map<String, Object> receiveParams = new HashMap<>();
            receiveParams.put("sendUserId", sendUserId); // sendUserId sendUserId
            receiveParams.put("receiveUserId", receiveUserId); // receiveUserId 是ReceiveUser的 id
            receiveParams.put("limitMessagesLength", limitMessagesLength); // 假设要限制返回的数量为 limitMessagesLength 条

            Map<String, Object> sendParams = new HashMap<>();
            sendParams.put("sendUserId", receiveUserId); // sendUserId 是ReceiveUser的 id
            sendParams.put("receiveUserId", sendUserId); // receiveUserId sendUserId
            sendParams.put("limitMessagesLength", limitMessagesLength); // 假设要限制返回的数量为 limitMessagesLength 条

            // 获取对方发送的信息
            List<Message> receiveMessageList = messageMapper.selectBySendUserAndReceiveUserLimitLength(receiveParams);
            // 获取发送给对方的信息
            List<Message> sendMessageList = messageMapper.selectBySendUserAndReceiveUserLimitLength(sendParams);
            List<Message> allMessageList = new ArrayList<>();
            allMessageList.addAll(receiveMessageList);
            allMessageList.addAll(sendMessageList);
            List<Message> sortedMessageList = allMessageList.stream()
                    .sorted(Comparator.comparing(Message::getCreateTime))
                    .collect(Collectors.toList());

            // 设置已读
            List<Message> noReadMessageList = receiveMessageList.stream()
                    .filter(o -> "0".equals(o.getIsRead()))
                    .peek(message -> message.setIsRead("1"))
                    .collect(Collectors.toList());
            if (noReadMessageList.size() > 0) {
                messageMapper.update(noReadMessageList);
            }
            return sortedMessageList;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    @Override
    // 获取所有数据
    public List<MessageForm> findAllMessageForm(String userId) throws Exception {
        try {

            Map<String, WebSocket> users = webSocketUtil.getUsers();
            Set<String> ids = users.keySet();
            AssertUtils.isError(StringUtils.isEmpty(userId), "用户编号不能为空!");
            List<MessageForm> messageFormList = new ArrayList<>();
            SysUser loginUser = userMapper.selectUserById(Long.valueOf(userId));
            AssertUtils.isError(null == loginUser, "用户编号:" + userId + "不存在!");
            messageFormList.addAll(findAllMessageChatDataWithLoginUserId(userId));
            // 判断ids是否在messageFormList的sendUser的Id中，不是则获取新的数据到messageFormList
            for (String id : ids) {
                if (!messageFormList.stream().map(o -> o.getSendUser().getUserId())
                        .collect(Collectors.toList())
                        .contains(Long.valueOf(id))) {
                    MessageForm messageForm = new MessageForm();
                    SysUser sendUserData = userMapper.selectUserById(Long.valueOf(id));
                    if (null == sendUserData) {
                        continue;
                    }
                    List<Message> allMessageList = findBothMessages(userId, id,
                            limitMessagesLength, messageMapper);
                    messageForm.setMessages(allMessageList);
                    messageForm.setSendUser(sendUserData);
                    messageForm.setReceiveUser(loginUser);
                    messageForm.setIsOnline(true);
                    messageForm.setNoReadMessageLength(0);
                    messageForm.setLastMessage("");
                    messageFormList.add(messageForm);
                }
            }

            // 获取所有messageFormList的sendUser的userId,
            List<Long> sendUserIds = messageFormList.stream().map(MessageForm::getSendUser)
                    .map(SysUser::getUserId).collect(Collectors.toList());
            //排除自身loginuserid
            sendUserIds.add(Long.valueOf(userId));

            // 如果获取到的用户少于10个，则补齐剩余数量的用户数据,这里补齐的是从没和自己聊天过的用户
            if (sendUserIds.size() < limitUserLength) {
                Integer leaveCount = limitUserLength - sendUserIds.size();
//                Where where = new Where();
//                where.notIn("user_id", sendUserIds.toArray());
//                where.limit(leaveCount);
                Map<String, Object> params = new HashMap<>();
                params.put("list", sendUserIds); // excludeIds 是要排除的 id 列表
                params.put("leaveCount", leaveCount); // 假设要限制返回的数量为 10 条
                List<SysUser> userList = userMapper.selectNotInIds(params);

                if (null != userList && userList.size() > 0) {
                    for (SysUser user : userList) {
                        MessageForm messageForm = new MessageForm();
                        messageForm.setSendUser(user);
                        messageForm.setReceiveUser(loginUser);
                        messageForm.setIsOnline(false);
                        messageForm.setNoReadMessageLength(0);
                        messageForm.setLastMessage("");
                        messageFormList.add(messageForm);
                    }
                }
            }

            // 按照在线状态为true，有聊天记录的优先展示
            messageFormList.sort((o1, o2) -> {
                if (o1.getIsOnline() && o2.getIsOnline()) {
                    return o2.getMessages().size() - o1.getMessages().size();
                } else if (o1.getIsOnline()) {
                    return -1;
                } else if (o2.getIsOnline()) {
                    return 1;
                } else {
                    return o2.getMessages().size() - o1.getMessages().size();
                }
            });

            return messageFormList;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    @Override
    // 获取登录用户所有聊过天的记录数据
    public List<MessageForm> findAllMessageChatDataWithLoginUserId(String userId)
            throws Exception {
        try {
            Map<String, WebSocket> users = webSocketUtil.getUsers();
            Set<String> ids = users.keySet();
            AssertUtils.isError(StringUtils.isEmpty(userId), "用户编号不能为空!");
            List<MessageForm> messageFormList = new ArrayList<>();
            SysUser loginUser = userMapper.selectUserById(Long.valueOf((userId)));
            AssertUtils.isError(null == loginUser, "用户编号:" + userId + "不存在!");
            // 获取所有有发送信息给自己聊天的用户
            List<String> allSendUsers =  messageMapper.selectByReceiveUser(userId).stream()
                    .map(Message::getSendUser).distinct().collect(Collectors.toList());
            for (String sendUser : allSendUsers) {
                // 发送人的用户信息
                MessageForm messageForm = new MessageForm();
                SysUser sendUserData = userMapper.selectUserById(Long.valueOf((sendUser)));
                if (null == sendUserData) {
                    continue;
                }
                Map<String, Object> receiveParams = new HashMap<>();
                receiveParams.put("sendUserId", sendUser); // sendUserId sendUserId
                receiveParams.put("receiveUserId", userId); // receiveUserId 是ReceiveUser的 id
                receiveParams.put("limitMessagesLength", limitMessagesLength); // 假设要限制返回的数量为 limitMessagesLength 条

                Map<String, Object> sendParams = new HashMap<>();
                sendParams.put("sendUserId", userId); // sendUserId 是ReceiveUser的 id
                sendParams.put("receiveUserId", sendUser); // receiveUserId sendUserId
                sendParams.put("limitMessagesLength", limitMessagesLength); // 假设要限制返回的数量为 limitMessagesLength 条
                // 获取对方发送的信息
                List<Message> receiveMessageList =  messageMapper.selectBySendUserAndReceiveUserLimitLength(receiveParams);
                // 获取发送给对方的信息
                List<Message> sendMessageList =  messageMapper.selectBySendUserAndReceiveUserLimitLength(sendParams);
                List<Message> allMessageList = new ArrayList<>();
                allMessageList.addAll(receiveMessageList);
                allMessageList.addAll(sendMessageList);

                List<Message> sortedMessageList = allMessageList.stream()
                        .sorted(Comparator.comparing(Message::getCreateTime))
                        .collect(Collectors.toList());
                // 赋值最新消息
                messageForm.setLastMessage(
                        sortedMessageList.size() > 0 ? sortedMessageList.get(sortedMessageList.size() - 1)
                                .getContent() : "");
                // 赋值聊天记录
                messageForm.setMessages(sortedMessageList);
                // 赋值未读消息
                messageForm.setNoReadMessageLength(
                        receiveMessageList.stream().filter(o -> "0".equals(o.getIsRead())).collect(
                                Collectors.toList()).size());
                // 赋值发送人
                messageForm.setSendUser(sendUserData);
                // 赋值接收人
                messageForm.setReceiveUser(loginUser);
                // 赋值是否在线
                messageForm.setIsOnline(ids.contains(sendUser));
                messageFormList.add(messageForm);
            }
            // 获取只有自己发送信息给别人的记录的用户
            List<String> allSendToUsers =  messageMapper.selectBySendUser(userId).stream()
                    .map(Message::getReceiveUser).distinct().collect(Collectors.toList());
            for (String receiveUser : allSendToUsers) {
                // 判断messageFormList的sendUser的userId是否包含receiveUser，有则说明已经存在了
                if (messageFormList.stream()
                        .anyMatch(o -> o.getSendUser().getUserName().equals(receiveUser))) {
                    continue;
                }
                MessageForm messageForm = new MessageForm();
                SysUser receiveUserData = userMapper.selectUserById(Long.valueOf((receiveUser)));
                if (null == receiveUserData) {
                    continue;
                }
                messageForm.setReceiveUser(loginUser);
                messageForm.setSendUser(receiveUserData);
                messageForm.setLastMessage("");
                messageForm.setNoReadMessageLength(0);

                Map<String, Object> sendParams = new HashMap<>();
                sendParams.put("sendUserId", userId); // sendUserId 是ReceiveUser的 id
                sendParams.put("receiveUserId", receiveUser); // receiveUserId sendUserId
                sendParams.put("limitMessagesLength", limitMessagesLength); // 假设要限制返回的数量为 limitMessagesLength 条

                List<Message> sendMessageList = messageMapper.selectBySendUserAndReceiveUserLimitLength(sendParams);
                // 按照CreateTime排序从小到大
                messageForm.setMessages(sendMessageList.stream()
                        .sorted(Comparator.comparing(Message::getCreateTime))
                        .collect(Collectors.toList()));
                messageForm.setIsOnline(ids.contains(receiveUser));
                messageFormList.add(messageForm);
            }
            return messageFormList;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    @Override
    // 用户区查到的数据，有用户名就查用户名对应用户数据和聊天记录，没有默认查300个用户（配置）
    public List<MessageForm> searchUserForForm(String userId, String username)
            throws Exception {
        try {
            List<MessageForm> messageFormList = new ArrayList<>();
            AssertUtils.isError(StringUtils.isEmpty(userId), "登录用户不能为空!");
            SysUser loginUser = userMapper.selectUserById(Long.valueOf((userId)));
            AssertUtils.isError(null == loginUser, "登录用户不存在!");
            if (!username.equals("all")) {
                List<SysUser> userList = userMapper.selectListByUserName(username);
                Map<String, WebSocket> users = webSocketUtil.getUsers();
                Set<String> ids = users.keySet();
                for (SysUser user : userList) {
                    SysUser sendUserData = userMapper.selectUserById(user.getUserId());
                    if (null == sendUserData) {
                        continue;
                    }
                    MessageForm messageForm = new MessageForm();
                    messageForm.setSendUser(sendUserData);
                    messageForm.setReceiveUser(loginUser);
                    messageForm.setIsOnline(ids.contains(user.getUserId().toString()));

                    Map<String, Object> receiveParams = new HashMap<>();
                    receiveParams.put("sendUserId", sendUserData.getUserId().toString()); // sendUserId sendUserId
                    receiveParams.put("receiveUserId", loginUser.getUserId().toString()); // receiveUserId 是ReceiveUser的 id
                    receiveParams.put("limitMessagesLength", limitMessagesLength); // 假设要限制返回的数量为 limitMessagesLength 条

                    Map<String, Object> sendParams = new HashMap<>();
                    sendParams.put("sendUserId", loginUser.getUserId().toString()); // sendUserId 是ReceiveUser的 id
                    sendParams.put("receiveUserId", sendUserData.getUserId().toString()); // receiveUserId sendUserId
                    sendParams.put("limitMessagesLength", limitMessagesLength); // 假设要限制返回的数量为 limitMessagesLength 条

                    // 获取对方发送的信息
                    List<Message> receiveMessageList = messageMapper.selectBySendUserAndReceiveUserLimitLength(receiveParams);
                    // 获取发送给对方的信息
                    List<Message> sendMessageList = messageMapper.selectBySendUserAndReceiveUserLimitLength(sendParams);
                    List<Message> allMessages = new ArrayList<>();
                    allMessages.addAll(receiveMessageList);
                    allMessages.addAll(sendMessageList);
                    allMessages.sort((o1, o2) -> {
                        if (o1.getCreateTime().before(o2.getCreateTime())) {
                            return -1;
                        } else if (o1.getCreateTime().after(o2.getCreateTime())) {
                            return 1;
                        } else {
                            return 0;
                        }
                    });
                    if (allMessages.size() > 0) {
                        messageForm.setLastMessage(allMessages.get(allMessages.size() - 1).getContent());
                    } else {
                        messageForm.setLastMessage("");
                    }
                    messageForm.setMessages(allMessages);
                    // 获取allMessages中isRead为0的数量
                    messageForm.setNoReadMessageLength(
                            (int) allMessages.stream().filter(message -> "0".equals(message.getIsRead()))
                                    .count());
                    messageFormList.add(messageForm);
                }
            } else {
                messageFormList.addAll(findAllMessageForm(userId));
            }
            return messageFormList;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    @Override
    public List<Message> findBothMessages(String sendUserId, String receiveUserId,
                                          Integer limitMessageLength,
                                          MessageMapper messageMapper) {

        Map<String, Object> receiveParams = new HashMap<>();
        receiveParams.put("sendUserId", receiveUserId); // sendUserId sendUserId
        receiveParams.put("receiveUserId", sendUserId); // receiveUserId 是ReceiveUser的 id
        receiveParams.put("limitMessagesLength", limitMessageLength); // 假设要限制返回的数量为 limitMessagesLength 条

        Map<String, Object> sendParams = new HashMap<>();
        sendParams.put("sendUserId", sendUserId); // sendUserId 是ReceiveUser的 id
        sendParams.put("receiveUserId", receiveUserId); // receiveUserId sendUserId
        sendParams.put("limitMessagesLength", limitMessageLength); // 假设要限制返回的数量为 limitMessagesLength 条

        List<Message> receiveMessageList = messageMapper.selectBySendUserAndReceiveUserLimitLength(receiveParams);
        List<Message> sendMessageList = messageMapper.selectBySendUserAndReceiveUserLimitLength(sendParams);

        List<Message> allMessageList = new ArrayList<>();
        allMessageList.addAll(receiveMessageList);
        allMessageList.addAll(sendMessageList);
        allMessageList.stream().sorted(Comparator.comparing(Message::getCreateTime))
                .collect(Collectors.toList());
        return allMessageList;
    }
}
